#ifndef ZHILAISDK_CMULTIPLEDATALINK_H_
#define ZHILAISDK_CMULTIPLEDATALINK_H_

#include <iostream>
#include <mutex>

#include "zlbase/zlbase.h"

/// \brief 专为智莱标准快件箱监控板设计的链路类
///
/// 该链路类会监听两个本地UDP端口，上位机通过端口1（如：30000）将指令发送到下位机，然后
/// 下位机会把回复报文发送到上位机的端口2（端口1 + 1，即：30001）
class CMultipleDatalink : public zl::zlbase::IBaseDatalink
{
public:
    CMultipleDatalink(std::shared_ptr<zl::zlbase::IBaseDatalink> sender,
                      std::shared_ptr<zl::zlbase::IBaseDatalink> reader) :
        sender_(sender),
        reader_(reader)
    {
    }
    ~CMultipleDatalink()
    {
        sender_.reset();
        reader_.reset();
    }

    void SetOption(const zl::zlbase::DatalinkOption &opt) override {}

    zl::zlbase::DatalinkOption GetOption() override
    {
        return zl::zlbase::DatalinkOption();
    }

    inline void AcquireOwnership(bool flag) override
    {
        // reader_->AcquireOwnership(flag);
        // sender_->AcquireOwnership(flag);
    }

    bool IsOpen() override
    {
        return reader_->IsOpen() && sender_->IsOpen();
    }

    int32_t Open() override
    {
        int32_t f1(0), f2(0);
        if (!reader_->IsOpen())
        {
            f1 = reader_->Open();
        }
        if (!sender_->IsOpen())
        {
            f2 = sender_->Open();
        }

        if (f1 != zl::zlbase::ZLResult_Success || f2 != zl::zlbase::ZLResult_Success)
        {
            return zl::zlbase::ZLResult_Fail;
        }

        return zl::zlbase::ZLResult_Success;
    }

    int32_t Close() override
    {
        return zl::zlbase::ZLResult_Success;
    }

    int32_t Read(unsigned char *buff, size_t len) override
    {
        return Read(buff, len, 300);
    }

    int32_t Read(unsigned char *buff, size_t len, int32_t timeout) override
    {
        return reader_->Read(buff, len, timeout);
    }

    int32_t Read(unsigned char *buff, size_t len, size_t count, int32_t timeout) override
    {
        return reader_->Read(buff, len, timeout);
    }

    int32_t Write(const unsigned char *buff, size_t len) override
    {
        return sender_->Write(buff, len);
    }

    int32_t Write(const unsigned char *buff, size_t len, int32_t timeout) override
    {
        return sender_->Write(buff, len, timeout);
    }

protected:
    int32_t sync_read(unsigned char *buff, size_t len, int32_t timeout);
    int32_t sync_write(const unsigned char *buff, size_t len, int32_t timeout);
    void notify_readsome(const unsigned char *data, size_t len);
    void notify_writesome(const unsigned char *data, size_t len);

private:
    std::shared_ptr<zl::zlbase::IBaseDatalink> sender_;
    std::shared_ptr<zl::zlbase::IBaseDatalink> reader_;
};

#endif  // ZHILAISDK_CMULTIPLEDATALINK_H_